#include "fileprocessingtask.h"
#include "fileidentitymanager.h"
#include "fileprocessworker.h"
#include "unifiedcachemanager.h"
#include "systemconfig.h"
#include "systemconfigmanager.h"
#include "dpiservice.h"
#include <QDebug>
#include <QFileInfo>
#include <QDir>
#include <QDateTime>
#include <QUuid>
#include <QMutexLocker>
#include <QThread>
#include <QImage>
#include <QPainter>
#include <QFont>
#include <QSettings>
// FileProcessingTask 实现
FileProcessingTask::FileProcessingTask(const QString& filePath, 
                                     const QString& cacheDir,
                                     int fileIndex,
                                     QObject* parent)
    : QObject(parent)
    , m_filePath(filePath)
    , m_cacheDir(cacheDir)
    , m_fileIndex(fileIndex)
    , m_priority(5) // 默认优先级
    , m_cancelled(false)
{
    m_taskId = generateTaskId();
    m_estimatedMemory = estimateMemoryUsage(filePath);
    m_estimatedDuration = estimateDuration(filePath);
}
FileProcessingTask::~FileProcessingTask()
{
}
void FileProcessingTask::execute()
{
    updateProgress(0, "开始处理文件");
    try {
        bool success = processFile();
        if (checkCancellation()) {
            notifyCompletion(false, "任务被取消");
            return;
        }
        if (success) {
            updateProgress(100, "处理完成");
            notifyCompletion(true);
        } else {
            notifyCompletion(false, "文件处理失败");
        }
    } catch (const std::exception& e) {
        QString error = QString("任务执行异常: %1").arg(e.what());
        notifyCompletion(false, error);
    } catch (...) {
        QString error = "未知异常";
        notifyCompletion(false, error);
    }
}
void FileProcessingTask::cancel()
{
    QMutexLocker locker(&m_cancelMutex);
    m_cancelled = true;
}
void FileProcessingTask::setProgressCallback(std::function<void(int, const QString&)> callback)
{
    m_progressCallback = callback;
}
void FileProcessingTask::setCompletionCallback(std::function<void(bool, const QString&)> callback)
{
    m_completionCallback = callback;
}
void FileProcessingTask::updateProgress(int progress, const QString& status)
{
    // 发送信号
    emit progressUpdated(m_taskId, progress, status);
    // 调用回调函数
    if (m_progressCallback) {
        m_progressCallback(progress, status);
    }
}
void FileProcessingTask::notifyCompletion(bool successful, const QString& errorMessage)
{
    // 发送信号
    emit taskCompleted(m_taskId, successful, errorMessage);
    // 调用回调函数
    if (m_completionCallback) {
        m_completionCallback(successful, errorMessage);
    }
}
bool FileProcessingTask::processFile()
{
    updateProgress(5, "检查文件");
    // 检查文件是否存在
    QFileInfo fileInfo(m_filePath);
    if (!fileInfo.exists()) {
        return false;
    }
    if (checkCancellation()) return false;
    updateProgress(10, "使用真正的文件处理器");
    // Martin Fowler重构：使用真正的FileProcessWorker进行文件处理，注入DPI配置
    DpiConfiguration dpiConfig = getCurrentDpiConfiguration();
    FileProcessWorker worker(m_fileIndex, m_filePath, dpiConfig);
    // 连接进度信号
    connect(&worker, &FileProcessWorker::progressUpdated, 
            [this](int fileIndex, const UnifiedFileInfo& info) {
                if (fileIndex == m_fileIndex) {
                    updateProgress(info.progress, info.statusText);
                }
            });
    // 执行处理
    worker.run();
    if (checkCancellation()) return false;
    updateProgress(90, "验证结果");
    // 验证处理结果 - 使用UnifiedCacheManager的缓存目录
    if (!validateResults()) {
        return false;
    }
    // 如果验证通过，说明处理成功
    return true;
}
bool FileProcessingTask::validateResults()
{
    // 使用UnifiedCacheManager检查缓存结果
    UnifiedCacheManager* cacheManager = UnifiedCacheManager::instance();
    if (!cacheManager) {
        return false;
    }
    // 获取文件标识
    QString fileIdentity = FileIdentityManager::getFileIdentity(m_filePath);
    // 检查是否有缓存页面
    int pageCount = 0;
    for (int i = 0; i < 100; ++i) { // 最多检查100页
        if (cacheManager->isCached(fileIdentity, i)) {
            pageCount++;
        } else {
            break;
        }
    }
    if (pageCount == 0) {
        return false;
    }
    return true;
}
QString FileProcessingTask::generateTaskId() const
{
    QString fileIdentity = FileIdentityManager::getFileIdentity(m_filePath);
    QString timestamp = QString::number(QDateTime::currentMSecsSinceEpoch());
    return QString("FileTask_%1_%2").arg(fileIdentity).arg(timestamp);
}
qint64 FileProcessingTask::estimateMemoryUsage(const QString& filePath) const
{
    QFileInfo fileInfo(filePath);
    qint64 fileSize = fileInfo.size();
    // Martin Fowler修复：更现实的内存估算
    // 过于保守的估算导致任务永远不被执行
    FileType type = detectFileType(filePath);
    switch (type) {
        case FileType::PDF:
            // 修复：降低PDF内存估算，避免任务被阻塞
            return qMin(fileSize / 2, static_cast<qint64>(200 * 1024 * 1024)); // 最大200MB
        case FileType::Image:
            return qMin(fileSize, static_cast<qint64>(100 * 1024 * 1024)); // 最大100MB
        default:
            return qMin(fileSize, static_cast<qint64>(50 * 1024 * 1024)); // 最大50MB
    }
}
qint64 FileProcessingTask::estimateDuration(const QString& filePath) const
{
    QFileInfo fileInfo(filePath);
    qint64 fileSize = fileInfo.size();
    // 基于文件大小估算处理时间（毫秒）
    // 假设处理速度为1MB/秒
    qint64 baseDuration = (fileSize / (1024 * 1024)) * 1000;
    // 最少1秒，最多30秒
    return std::max(1000LL, std::min(baseDuration, 30000LL));
}
bool FileProcessingTask::checkCancellation()
{
    QMutexLocker locker(&m_cancelMutex);
    return m_cancelled;
}
FileProcessingTask::FileType FileProcessingTask::detectFileType(const QString& filePath) const
{
    QString extension = QFileInfo(filePath).suffix().toLower();
    if (extension == "pdf") {
        return FileType::PDF;
    } else if (extension == "jpg" || extension == "jpeg" || 
               extension == "png" || extension == "bmp" || 
               extension == "gif" || extension == "tiff") {
        return FileType::Image;
    }
    return FileType::Unknown;
}
// Martin Fowler重构：DPI配置获取 - 使用DpiService统一管理
DpiConfiguration FileProcessingTask::getCurrentDpiConfiguration() const
{
    // Martin Fowler重构：使用DpiService获取缓存生成DPI
    double cacheDpi = DpiSvc.getDpiForPurpose(DpiService::DpiPurpose::CacheGeneration);
    // 文件处理任务只需要缓存生成DPI
    DpiConfiguration dpiConfig(cacheDpi, cacheDpi);
    return dpiConfig;
}
// BatchFileProcessingTask 实现
BatchFileProcessingTask::BatchFileProcessingTask(const QStringList& filePaths,
                                               const QString& baseCacheDir,
                                               QObject* parent)
    : QObject(parent)
    , m_filePaths(filePaths)
    , m_baseCacheDir(baseCacheDir)
    , m_cancelled(false)
{
    m_batchId = generateBatchId();
}
BatchFileProcessingTask::~BatchFileProcessingTask()
{
}
void BatchFileProcessingTask::execute()
{
    updateProgress(0, "开始批量处理");
    try {
        bool success = processBatch();
        if (checkCancellation()) {
            notifyCompletion(false, "任务被取消");
            return;
        }
        if (success) {
            updateProgress(100, "批量处理完成");
            notifyCompletion(true);
        } else {
            notifyCompletion(false, "批量处理失败");
        }
    } catch (const std::exception& e) {
        QString error = QString("批量任务异常: %1").arg(e.what());
        notifyCompletion(false, error);
    } catch (...) {
        QString error = "未知异常";
        notifyCompletion(false, error);
    }
}
qint64 BatchFileProcessingTask::getEstimatedMemory() const
{
    qint64 totalMemory = 0;
    for (const QString& filePath : m_filePaths) {
        QFileInfo fileInfo(filePath);
        totalMemory += fileInfo.size() * 2; // 估算每个文件需要2倍大小的内存
    }
    return totalMemory;
}
qint64 BatchFileProcessingTask::getEstimatedDuration() const
{
    // 批量处理时间为单个文件时间的总和
    qint64 totalDuration = 0;
    for (const QString& filePath : m_filePaths) {
        QFileInfo fileInfo(filePath);
        qint64 fileSize = fileInfo.size();
        qint64 fileDuration = (fileSize / (1024 * 1024)) * 1000;
        totalDuration += std::max(1000LL, std::min(fileDuration, 30000LL));
    }
    return totalDuration;
}
void BatchFileProcessingTask::cancel()
{
    QMutexLocker locker(&m_cancelMutex);
    m_cancelled = true;
}
void BatchFileProcessingTask::setProgressCallback(std::function<void(int, const QString&)> callback)
{
    m_progressCallback = callback;
}
void BatchFileProcessingTask::setCompletionCallback(std::function<void(bool, const QString&)> callback)
{
    m_completionCallback = callback;
}
void BatchFileProcessingTask::updateProgress(int progress, const QString& status)
{
    // 发送信号
    emit progressUpdated(m_batchId, progress, status);
    // 调用回调函数
    if (m_progressCallback) {
        m_progressCallback(progress, status);
    }
}
void BatchFileProcessingTask::notifyCompletion(bool successful, const QString& errorMessage)
{
    // 发送信号
    emit taskCompleted(m_batchId, successful, errorMessage);
    // 调用回调函数
    if (m_completionCallback) {
        m_completionCallback(successful, errorMessage);
    }
}
bool BatchFileProcessingTask::processBatch()
{
    int totalFiles = m_filePaths.size();
    int processedFiles = 0;
    for (const QString& filePath : m_filePaths) {
        if (checkCancellation()) return false;
        // 生成缓存目录
        QString fileIdentity = FileIdentityManager::getFileIdentity(filePath);
        QString cacheKey = FileIdentityManager::getCacheKey(fileIdentity);
        QString cacheDir = m_baseCacheDir + "/" + cacheKey;
        // 创建单个文件处理任务
        FileProcessingTask fileTask(filePath, cacheDir);
        // 设置进度回调
        fileTask.setProgressCallback([this, processedFiles, totalFiles](int progress, const QString& status) {
            int overallProgress = (processedFiles * 100 + progress) / totalFiles;
            updateProgress(overallProgress, QString("处理文件 %1/%2: %3").arg(processedFiles + 1).arg(totalFiles).arg(status));
        });
        // 执行任务
        fileTask.execute();
        processedFiles++;
        // 更新整体进度
        int overallProgress = (processedFiles * 100) / totalFiles;
        updateProgress(overallProgress, QString("已完成 %1/%2 个文件").arg(processedFiles).arg(totalFiles));
    }
    return true;
}
bool BatchFileProcessingTask::checkCancellation()
{
    QMutexLocker locker(&m_cancelMutex);
    return m_cancelled;
}
QString BatchFileProcessingTask::generateBatchId() const
{
    QString timestamp = QString::number(QDateTime::currentMSecsSinceEpoch());
    return QString("BatchTask_%1_%2").arg(m_filePaths.size()).arg(timestamp);
}
